

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;

public class TickTacToe extends JApplet {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	//indicate which player has a turn
	//initially it is in the Black player
	private String whoseTurn = "Black";
	
	//create and initialize cells
	private Cell[][] cells = new Cell[15][15];
	
	//create and initialize a status label - default is Black
	private JLabel jlblStatus = new JLabel("Black's turn to play");
	
	//initialize UI, constructor
	public TickTacToe(){
		//panel to hold cells
		JPanel p = new JPanel(new GridLayout(15,15,0,0));
		setSize(500,500);
		for (int i = 0; i < cells.length; i++) {
			for (int j = 0; j < cells[0].length; j++) {
				p.add(cells[i][j] = new Cell());
			}
		}
		//set line borders on the cell's panel and status label
		p.setBorder(new LineBorder(Color.red,1));
		jlblStatus.setBorder(new LineBorder(Color.yellow, 1));
		
		//place the panel and the label for the applet
		add(p, BorderLayout.CENTER);
		add(jlblStatus, BorderLayout.SOUTH);
	}
	
	//determine whether the cells are all occupied
	public boolean isFull(){
		for (int i = 0; i < cells.length; i++) {
			for (int j = 0; j < cells[0].length; j++) {
				if(cells[i][j].getToken() == " "){
					return false;
				}
			}
		}
		return true;
	}
	
	//determine whether the player with the specified token wins
	public boolean isWon(String token){
		for (int i = 0; i < cells.length; i++) {
			if((cells[i][0].getToken() == token) && (cells[i][1].getToken() == token) && (cells[i][2].getToken() ==token)){
				return true;
			}
			for (int j = 0; j < cells[0].length; j++) {
				if((cells[0][j].getToken() == token) && (cells[1][j].getToken() == token) && (cells[2][j].getToken() ==token)){
					return true;
				}
			}
		}
		if((cells[0][0].getToken() == token) && (cells[1][1].getToken() == token) && (cells[2][2].getToken() ==token)){
			return true;
		}
		if((cells[0][2].getToken() == token) && (cells[1][1].getToken() == token) && (cells[2][0].getToken() ==token)){
			return true;
		}
		return false;
	}
	
	//an inner class for a cell
	public class Cell extends JPanel{
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		
		//Token used for this cell
		private String token = " ";
		
		//constructor
		public Cell(){
			setSize(500,500);
			setBorder(new LineBorder(Color.black, 1));
			addMouseListener(new MyMouseListener());
		}
		//return token
		public String getToken(){
			return token;
		}
		//set a new token
		public void setToken(String c){
			token = c;
			repaint();
		}
		@Override //paint the cell
		protected void paintComponent(Graphics g){
			super.paintComponent(g);
			g.setColor(Color.black);
			g.drawLine(25, 0, 25, 50);
			g.drawLine(0, 25, 50, 25);
			if(token == "Black"){
				//g.drawLine(10, 10, getWidth() - 10, getHeight() - 10);
				//g.drawLine(getWidth() - 10, 10, 10, getHeight() - 10);
				g.fillOval(10, 10, getWidth() - 20, getHeight() - 20);
			}else if(token == "White"){
				g.drawOval(10, 10, getWidth() - 20, getHeight() - 20);
			}
		}
		private class MyMouseListener extends MouseAdapter{
			@Override //handle mouse click on a cell
			public void mouseClicked(MouseEvent e){
				//if cell is empty and the game is not over
				if(token == " " && whoseTurn != " "){
					//set token in the cell
					setToken(whoseTurn);
					
					//check game status
					if(isWon(whoseTurn)){
						jlblStatus.setText(whoseTurn + " won! The game is over.");
						whoseTurn = " "; //game is over
					}else if (isFull()){
						jlblStatus.setText("Draw! The game is over.");
					}else{
						//change the turn
						whoseTurn = (whoseTurn.equals("Black")) ? "White" : "Black";
						
						//display whose turn
						jlblStatus.setText(whoseTurn + "'s turn");
					}
					
				}
			}
		}
	}

}
